<?php

namespace backend\models;

use mdm\admin\components\Helper;
use Yii;
use yii\base\Module;

/**
 * This is the model class for table "app_modules".
 *
 * @property string $id 别名
 * @property string $type 类型
 * @property string $name 名称
 * @property string $class 对应类名
 * @property string $config 配置
 * @property int $status 状态 0禁用 1启用
 * @property string $created_at 创建时间
 * @property array $statusTexts 状态
 * @property array $typeTexts 状态
 */
class AppModules extends \common\models\BaseModels
{

    const CACHE_KEY = 'AppModulesCacheKey';

    /**
     * @var array
     */
    public $switchValues = [
        'status' => [
            'on' => 1,
            'off' => 0,
        ],
    ];

    /**
     * @var array
     */
    public $typeTexts = [
        'backend' => 'backend',
        'frontend' => 'frontend',
        'console' => 'console',
    ];

    /**
     * @var array
     */
    public $statusTexts = [
        1 => '启用',
        0 => '禁用',
    ];

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'app_modules';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['id', 'name', 'class'], 'required'],
            [['status'], 'integer'],
            [['created_at'], 'safe'],
            [['id', 'name'], 'string', 'max' => 50],
            [['type'], 'string', 'max' => 20],
            [['class'], 'string', 'max' => 100],
            [['config'], 'string', 'max' => 500],
            [['id'], 'unique'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => '别名',
            'type' => '类型',
            'name' => '名称',
            'class' => '对应类名',
            'config' => '配置',
            'status' => '状态',// 0禁用 1启用
            'created_at' => '创建时间',
        ];
    }

    /**
     * @var Module|null
     */
    private $module = null;

    public function beforeSave($insert)
    {
        if(parent::beforeSave($insert)){
            try {
                $config = json_decode($this->config,1);
                $config['class'] = $this->class;
                app()->setModule($this->id,$config);
                $this->module = app()->getModule($this->id);
                return true;
            }catch (\Exception $e){
                if(YII_DEBUG){
                    throw new \Exception($e->getMessage());
                }
                $this->addError('class','模块对应类名不存在!');
            }
        }

        return false;
    }

    /**
     * afterSave
     * @param bool $insert
     * @param array $changedAttributes
     * @return bool|void
     * @throws \Exception
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);

        try {
            if($this->module && $this->module->hasMethod('auth')){
                if($insert){
                    $this->status && $this->module->auth($this->id);
                }else{
                    isset($changedAttributes['status']) && $this->module->auth($this->id,!$changedAttributes['status']);
                }
            }
            return true;
        }catch (\Exception $e){
            exceptionFormat($e);
            if(YII_DEBUG){
                throw new \Exception($e->getMessage());
            }
            return false;
        } finally {
            cache()->delete(self::CACHE_KEY);
            Helper::invalidate();
            db()->enableQueryCache && db()->schema->refresh();
        }
    }

    /**
     * afterDelete
     */
    public function afterDelete()
    {
        try {
            $module = app()->getModule($this->id);
            if($module && $module->hasMethod('auth')){
                $module->auth($this->id,false);
            }
            parent::afterDelete();
        }catch (\Exception $e){
            if(YII_DEBUG){
                throw new \Exception($e->getMessage());
            }
        } finally {
            cache()->delete(self::CACHE_KEY);
            Helper::invalidate();
            db()->enableQueryCache && db()->schema->refresh();
        }
    }

}
